#include "core/renderwindow.h"
#include "core/logger.h"

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>

namespace engine {

	namespace core {
	
		RenderWindow::RenderWindow():
		m_Width(0),
		m_Height(0),
		m_ColourDepth(0),
		m_Top(0),
		m_Left(0),
		m_IsFullscreen(false) {
			
		}
		
		RenderWindow::~RenderWindow() {
			
		}
		
		void RenderWindow::setTitle(const string& title, const string& icon) {
			const char* ico = 0;

			SDL_WM_SetCaption(title.c_str(), 0);

			if (!icon.empty())	{
				ico = icon.c_str();
				SDL_WM_SetIcon(SDL_LoadBMP(ico), 0);
			}
		}
		
		bool RenderWindow::create(uint width, uint height, uint left, uint top,
								const string& title, bool fullscreen, 
								uint colourDepth) {
		
			Logger::getLogger("window")->debug("Creating the window.");
			
			// Initialize SDL
			if (SDL_Init(SDL_INIT_VIDEO) < 0) {
				Logger::getLogger("window")->error("Couldn't initialize SDL video");
				return false;
			}
			
			m_Width = width;
			m_Height = height;
			m_Left = left;
			m_Top = top;
			m_Name = title;
			m_IsFullscreen = fullscreen;
			m_ColourDepth = colourDepth;
			
			SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
			SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
			SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
			
			SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
			SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
			
			int flag = SDL_OPENGL;// | SDL_RESIZABLE;

			if (m_IsFullscreen) {
				flag |= SDL_FULLSCREEN;
			}
			
			if (!SDL_SetVideoMode(width, height, colourDepth, flag)) {
				Logger::getLogger("window")->error("Couldn't set video mode");
				return false;
			}
				
		    SDL_EnableUNICODE(1);
			SDL_ShowCursor(SDL_DISABLE);
			SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
			
			setTitle(title);
			resize(width, height);
			
			Logger::getLogger("window")->debug("Window creation complete");
			
			glDepthFunc(GL_LEQUAL);
			
			return true;
		}
	
		void RenderWindow::destroy() {
			SDL_WM_GrabInput(SDL_GRAB_OFF);
			SDL_ShowCursor(SDL_ENABLE);
			SDL_QuitSubSystem(SDL_INIT_VIDEO);
		}
	
		void RenderWindow::clearBuffers() {
			glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
			glLoadIdentity();
		}
		
		void RenderWindow::swapBuffers(bool waitForVSync) {
			SDL_GL_SwapBuffers();
		}
		
		void RenderWindow::resize(int w, int h) {
			if(h == 0)
				h = 1;

			float ratio = 1.0* w / h;

			// Reset the coordinate system before modifying
			glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			
			// Set the viewport to be the entire window
			glViewport(0, 0, w, h);

			// Set the correct perspective.
			gluPerspective(45, ratio, 10.0, 1000.0);
			glMatrixMode(GL_MODELVIEW);
			glLoadIdentity();	
		}
	}
}
